package bsc.ejb.facade;

import bsc.ejb.entity.ActionPlan;
import bsc.ejb.entity.ActionPlanPerson;
import bsc.ejb.entity.Area;
import bsc.ejb.entity.Attachment;
import bsc.ejb.entity.ColorimetrySettings;
import bsc.ejb.entity.Comparator;
import bsc.ejb.entity.ComparatorDimensionalCut;
import bsc.ejb.entity.Dimension;
import bsc.ejb.entity.DimensionMember;
import bsc.ejb.entity.DimensionalCut;
import bsc.ejb.entity.DimensionalCutMember;
import bsc.ejb.entity.ScoreDomain;
import bsc.ejb.entity.Employee;
import bsc.ejb.entity.Label;
import bsc.ejb.entity.Map;
import bsc.ejb.entity.MapDrawingSettings;
import bsc.ejb.entity.Milestone;
import bsc.ejb.entity.MilestoneTracer;
import bsc.ejb.entity.Note;
import bsc.ejb.entity.Objective;
import bsc.ejb.entity.Person;
import bsc.ejb.entity.PersonScoreCard;
import bsc.ejb.entity.PersonScoreDomain;
import bsc.ejb.entity.Perspective;
import bsc.ejb.entity.Pointer;
import bsc.ejb.entity.Project;
import bsc.ejb.entity.SRM;
import bsc.ejb.entity.SRMTopic;
import bsc.ejb.entity.ScoreCard;
import bsc.ejb.entity.ScoreCardDimension;
import bsc.ejb.entity.ScoreCardDomain;
import bsc.ejb.entity.ScoreCardRelation;
import bsc.ejb.entity.ScoreView;
import bsc.ejb.entity.Settings;
import bsc.ejb.entity.Task;
import bsc.ejb.entity.Theme;
import bsc.ejb.entity.Topic;
import bsc.ejb.entity.TopicScoreView;
import bsc.ejb.entity.Tracer;
import bsc.ejb.metadata.Activity;
import bsc.ejb.metadata.Alert;
import bsc.ejb.metadata.Colorimetry;
import bsc.ejb.metadata.Comparation;
import bsc.ejb.metadata.Formula;
import bsc.ejb.metadata.Framework;
import bsc.ejb.metadata.Graph;
import bsc.ejb.metadata.Icon;
import bsc.ejb.metadata.Lang;
import bsc.ejb.metadata.License;
import bsc.ejb.metadata.MapDrawing;
import bsc.ejb.metadata.NoteType;
import bsc.ejb.metadata.Profile;
import bsc.ejb.metadata.SMTP;
import bsc.ejb.metadata.TimePeriod;
import bsc.ejb.metadata.Unit;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author memozac
 */
@Stateless
public class BSCFacade implements BSCFacadeLocal {

    @PersistenceContext(unitName = "BSC-ejbPU")
    private EntityManager em;

    /**
     * <ENTITY>
     */
     //ActionPlan
    @Override
    public ActionPlan findActionPlan(Long idActionPlan) {
        return (ActionPlan) em.createQuery("select o from ActionPlan as o where o.idActionPlan = :idActionPlan").setParameter("idActionPlan", idActionPlan).getSingleResult();
    }

    @Override
    public List<ActionPlan> findActionPlan(ScoreCard scoreCard) {
        return em.createQuery("select o from ActionPlan as o where o.scoreCard.idScoreCard = :idScoreCard").setParameter("idScoreCard", scoreCard.getIdScoreCard()).getResultList();
    }

    // Update

    @Override
    public void updateActionPlan(ActionPlan actionPlan) {
        em.merge(actionPlan);
    }

    // Delete

    @Override
    public void deleteActionPlan(ActionPlan actionPlan) {
        em.remove(em.merge(actionPlan));
    }

    // ActionPlanPerson
    @Override
    public ActionPlanPerson findActionPlanPerson(ActionPlan actionPlan, ActionPlanPerson.Profile actionPlanPersonProfile) {
        return (ActionPlanPerson) em.createQuery("select o from ActionPlanPerson as o where o.profile = :actionPlanPersonProfile and o.actionPlan.idActionPlan = :idActionPlan").setParameter("actionPlanPersonProfile", actionPlanPersonProfile).setParameter("idActionPlan", actionPlan.getIdActionPlan()).getSingleResult();
    }

    //ActionPlanPerson

    // Find


    @Override
    public List<ActionPlanPerson> findActionPlanPerson() {
        return em.createQuery("select o from ActionPlanPerson as o").getResultList();
    }

    @Override
    public ActionPlanPerson findActionPlanPerson(Long idActionPlanPerson) {
        return (ActionPlanPerson) em.createQuery("select o from ActionPlanPerson as o where o.idActionPlanPerson = :idActionPlanPerson").setParameter("idActionPlanPerson", idActionPlanPerson).getSingleResult();
    }

    // Create

    @Override
    public void createActionPlanPerson(ActionPlanPerson actionPlanPerson) {
        em.persist(actionPlanPerson);
    }

    // Update

    @Override
    public void updateActionPlanPerson(ActionPlanPerson actionPlanPerson) {
        em.merge(actionPlanPerson);
    }

    // Delete

    @Override
    public void deleteActionPlanPerson(ActionPlanPerson actionPlanPerson) {
        em.remove(em.merge(actionPlanPerson));
    }

    // Area
    @Override
    public Area findArea(Long idArea) {
        return (Area) em.createQuery("select o from Area as o where o.idArea = :idArea").setParameter("idArea", idArea).getSingleResult();
    }

    // Attachment
    @Override
    public Attachment findAttachment(Long idAttachment) {
        return (Attachment) em.createQuery("select o from Attachment as o where o.idAttachment = :idAttachment").setParameter("idAttachment", idAttachment).getSingleResult();
    }

    @Override
    public List<Attachment> findAttachment(Note note) {
        return em.createQuery("select o from Attachment as o where o.note.idNote = :idNote").setParameter("idNote", note.getIdNote()).getResultList();
    }

    @Override
    public List<Attachment> findAttachment(ActionPlan actionPlan) {
        return em.createQuery("select o from Attachment as o where o.actionPlan.idActionPlan = :idActionPlan").setParameter("idActionPlan", actionPlan.getIdActionPlan()).getResultList();
    }
    // Comparator

    @Override
    public Comparator findComparator(Long idComparator) {
        return (Comparator) em.createQuery("select o from Comparator as o where o.idComparator = :idComparator").setParameter("idComparator", idComparator).getSingleResult();
    }

    @Override
    public Comparator findComparator(Pointer pointer, Comparation comparation) {
        return (Comparator) em.createQuery("select o from Comparator as o where o.comparation.idComparation = :idComparation and o.pointer.idScoreCard = :idScoreCard").setParameter("idScoreCard", pointer.getIdScoreCard()).setParameter("idComparation", comparation.getIdComparation()).getSingleResult();
    }

    @Override
    public List<Comparator> findComparator(Pointer pointer) {
        return em.createQuery("select o from Comparator as o where o.pointer.idScoreCard = :idScoreCard order by o.comparation.type").setParameter("idScoreCard", pointer.getIdScoreCard()).getResultList();
    }

    @Override
    public List<Comparator> findComparator(DimensionalCut dimensionalCut) {
        return em.createQuery("select o.comparator from ComparatorDimensionalCut as o where o.dimensionalCut.idScoreCard = :idScoreCard").setParameter("idScoreCard", dimensionalCut.getIdScoreCard()).getResultList();
    }

    //ComparatorDimensionalCut
    @Override
    public ComparatorDimensionalCut findComparatorDimensionalCut(Comparator comparator, DimensionalCut dimensionalCut, Date date) {
        return (ComparatorDimensionalCut) em.createQuery("select o from ComparatorDimensionalCut as o where o.comparator.idComparator = :idComparator and o.dimensionalCut.idScoreCard = :idScoreCard and o.registerDate = :date").setParameter("idComparator", comparator.getIdComparator()).setParameter("idScoreCard", dimensionalCut.getIdScoreCard()).setParameter("date", date).getSingleResult();
    }

    @Override
    public List<ComparatorDimensionalCut> findComparatorDimensionalCut(DimensionalCut dimensionalCut) {
        return em.createQuery("select o from ComparatorDimensionalCut as o where o.dimensionalCut.idScoreCard = :idScoreCard").setParameter("idScoreCard", dimensionalCut.getIdScoreCard()).getResultList();
    }

    @Override
    public List<Date> findComparatorDimensionalCutDate(DimensionalCut dimensionalCut) {
        return em.createQuery("select distinct o.registerDate from ComparatorDimensionalCut as o where o.dimensionalCut.idScoreCard = :idScoreCard").setParameter("idScoreCard", dimensionalCut.getIdScoreCard()).getResultList();
    }

    @Override
    public List<ComparatorDimensionalCut> findComparatorDimensionalCutDate(DimensionalCut dimensionalCut, Date date) {
        return em.createQuery("select o from ComparatorDimensionalCut as o where o.dimensionalCut.idScoreCard = :idScoreCard and o.registerDate = :date order by o.comparator.comparation.type").setParameter("idScoreCard", dimensionalCut.getIdScoreCard()).setParameter("date", date).getResultList();
    }

    @Override
    public Double findComparatorDimensionalCut(Comparator comparator, Date firstDate, Date lastDate) {

        String command = comparator.getSettings().getCommand().toString();//needs to define a temporality with the settings in ScoreCard
        //System.out.println("El command es: " + command);
        //System.out.println("First Date: " + firstDate);
        //System.out.println("Last Date: " + lastDate);
        // lookup of the dimensionalCuts of type TOTAL for that specific comparator
        return (Double) em.createQuery("select " + command + "(o.register) from ComparatorDimensionalCut as o where o.comparator.idComparator = :idComparator and " +
                "o.dimensionalCut.pointer.idScoreCard = :idScoreCard and o.dimensionalCut.type = :total and (o.registerDate >= :firstDate and o.registerDate <= :lastDate)")//  and (o.registerDate <= :inicialDate and o.registerDate >= :currentDate)
                .setParameter("idScoreCard", comparator.getPointer().getIdScoreCard()).setParameter("idComparator", comparator.getIdComparator()).setParameter("firstDate", firstDate).setParameter("lastDate", lastDate).setParameter("total", DimensionalCut.Type.TOTAL).getSingleResult();
    }

    @Override
    public Double findComparatorDimensionalCut(Comparator comparator, Date firstDate, Date lastDate, DimensionalCut dimensionalCut) {        
        if (dimensionalCut == null) {
            return this.findComparatorDimensionalCut(comparator, firstDate, lastDate);
        }

        String command = comparator.getSettings().getCommand().toString();//needs to define a temporality with the settings in ScoreCard
        // lookup of the dimensionalCuts of type TOTAL for that specific comparator
        return (Double) em.createQuery("select " + command + "(o.register) from ComparatorDimensionalCut as o where o.comparator.idComparator = :idComparator and " +
                "o.dimensionalCut.idScoreCard = :idScoreCard and o.dimensionalCut.idScoreCard = :idScoreCard and (o.registerDate >= :firstDate and o.registerDate <= :lastDate)")//  and (o.registerDate <= :inicialDate and o.registerDate >= :currentDate)
                .setParameter("idScoreCard", dimensionalCut.getIdScoreCard()).setParameter("idComparator", comparator.getIdComparator()).setParameter("firstDate", firstDate).setParameter("lastDate", lastDate).setParameter("idScoreCard", dimensionalCut.getIdScoreCard()).getSingleResult();
    }

    // Dimension
    @Override
    public List<Dimension> findDimension() {
        return em.createQuery("select o from Dimension as o").getResultList();
    }

    @Override
    public Dimension findDimension(Long idDimension) {
        return (Dimension) em.createQuery("select o from Dimension as o where o.idDimension = :idDimension").setParameter("idDimension", idDimension).getSingleResult();
    }

    @Override
    public List<Dimension> findDimension(ScoreCard scoreCard) {
        return em.createQuery("select o.dimension from ScoreCardDimension as o where o.scoreCard.idScoreCard = :idScoreCard").setParameter("idScoreCard", scoreCard.getIdScoreCard()).getResultList();
    }
    // DimensionMember

    @Override
    public List<DimensionMember> findDimensionMember(Boolean withBusyMembers) {
        if (withBusyMembers) {
            return em.createQuery("select o from DimensionMember as o ").getResultList();
        } else {
            return em.createQuery("select o from DimensionMember as o where o.dimension is NULL").getResultList();
        }
    }

    @Override
    public DimensionMember findDimensionMember(Long idDimensionMember) {
        return (DimensionMember) em.createQuery("select o from DimensionMember as o where o.idDimensionMember = :idDimensionMember").setParameter("idDimensionMember", idDimensionMember).getSingleResult();
    }

    @Override
    public List<DimensionMember> findDimensionMember(DimensionalCut dimensionalCut) {
        return em.createQuery("select o.dimensionMember from DimensionalCutMember as o where o.dimensionalCut.idScoreCard = :idScoreCard").setParameter("idScoreCard", dimensionalCut.getIdScoreCard()).getResultList();
    }

    @Override
    public List<DimensionMember> findDimensionMember(DimensionMember dimensionMember) {
        return em.createQuery("select o from DimensionMember as o where o.dimensionMember.idDimensionMember = :idDimensionMember").setParameter("idDimensionMember", dimensionMember.getIdDimensionMember()).getResultList();
    }

    @Override
    public List<DimensionMember> findRootDimensionMember(DimensionalCut dimensionalCut) {
        return em.createQuery("select o.dimensionMember from DimensionalCutMember as o where o.dimensionalCut.idScoreCard = :idScoreCard and o.dimensionMember.dimensionMember is null").setParameter("idScoreCard", dimensionalCut.getIdScoreCard()).getResultList();
    }

    @Override
    public List<DimensionMember> findDimensionMember(Dimension dimension) {
        return em.createQuery("select o from DimensionMember as o where o.dimension.idDimension = :idDimension").setParameter("idDimension", dimension.getIdDimension()).getResultList();
    }
    // DimensionalCut

    @Override
    public DimensionalCut findDimensionalCut(Long idScoreCard) {
        return (DimensionalCut) em.createQuery("select o from DimensionalCut as o where o.idScoreCard = :idScoreCard").setParameter("idScoreCard", idScoreCard).getSingleResult();
    }

    @Override
    public List<DimensionalCut> findDimensionalCut(DimensionMember dimensionMember) {
        return em.createQuery("select o.dimensionalCut from DimensionalCutMember as o where o.dimensionMember.idDimensionMember = :idDimensionMember").setParameter("idDimensionMember", dimensionMember.getIdDimensionMember()).getResultList();
    }

    @Override
    public List<DimensionalCut> findDimensionalCut(Comparator comparator) {
        return em.createQuery("select o.dimensionalCut from ComparatorDimensionalCut as o where o.comparator.idComparator = :idComparator").setParameter("idComparator", comparator.getIdComparator()).getResultList();
    }

    @Override
    public List<DimensionalCut> findDimensionalCut(Pointer pointer) {
        return em.createQuery("select o from DimensionalCut as o where o.pointer.idScoreCard = :idScoreCard").setParameter("idScoreCard", pointer.getIdScoreCard()).getResultList();
    }
    //DimensionalCutMember

    @Override
    public List<DimensionalCutMember> findDimensionalCutMember(DimensionalCut dimensionalcut) {
        return em.createQuery("select o from DimensionalCutMember as o where o.dimensionalCut.idScoreCard = :idScoreCard").setParameter("idScoreCard", dimensionalcut.getIdScoreCard()).getResultList();
    }
    // ScoreCardDimension

    @Override
    public ScoreCardDimension findScoreCardDimension(Long idScoreCardDimension) {
        return (ScoreCardDimension) em.createQuery("select o from ScoreCardDimension as o where o.idScoreCardDimension = :idScoreCardDimension").setParameter("idScoreCardDimension", idScoreCardDimension).getSingleResult();
    }

    @Override
    public List<ScoreCardDimension> findScoreCardDimension(ScoreCard scoreCard) {
        return em.createQuery("select o from ScoreCardDimension as o where o.scoreCard.idScoreCard = :idScoreCard").setParameter("idScoreCard", scoreCard.getIdScoreCard()).getResultList();
    }
    // ScoreDomain

    @Override
    public List<ScoreDomain> findScoreDomain() {
        return em.createQuery("select o from ScoreDomain as o").getResultList();
    }

    @Override
    public List<ScoreDomain> findScoreDomainSpecial(Long idScoreDomain) {
        return em.createQuery("select o from ScoreDomain as o where o.idScoreDomain != :idScoreDomain").setParameter("idScoreDomain", idScoreDomain).getResultList();
    }

    @Override
    public ScoreDomain findScoreDomain(Long idScoreDomain) {
        return (ScoreDomain) em.createQuery("select o from ScoreDomain as o where o.idScoreDomain = :idScoreDomain").setParameter("idScoreDomain", idScoreDomain).getSingleResult();
    }

    @Override
    public List<ScoreDomain> findScoreDomain(Person person) {
        return em.createQuery("select o.scoreDomain from PersonScoreDomain as o where o.person.idPerson = :idPerson").setParameter("idPerson", person.getIdPerson()).getResultList();
    }

    @Override
    public List<ScoreDomain> findScoreDomain(Person person, Boolean defaultDomain ) {
        return em.createQuery("select o.scoreDomain from PersonScoreDomain as o where o.person.idPerson = :idPerson and o.defaultDomain= :defaultDomain").setParameter("idPerson", person.getIdPerson()).setParameter("defaultDomain", defaultDomain).getResultList();
    }

    @Override
    public ScoreCardDomain findScoreCardDomain(Long idScoreCardDomain) {
        return (ScoreCardDomain) em.createQuery("select o from ScoreCardDomain as o where o.idScoreCardDomain = :idScoreCardDomain").setParameter("idScoreCardDomain", idScoreCardDomain).getSingleResult();
    }

    @Override
    public ScoreCardRelation findScoreCardRelation(Long idScoreCardRelation) {
        return (ScoreCardRelation) em.createQuery("select o from ScoreCardRelation as o where o.idScoreCardRelation = :idScoreCardRelation").setParameter("idScoreCardRelation", idScoreCardRelation).getSingleResult();
    }

    @Override
    public ScoreCardRelation findScoreCardRelation(Long idScoreCard, Long idOtherScoreCard) {
        //System.out.println("idScoreCard: "+idScoreCard +", " + idOtherScoreCard);
        return (ScoreCardRelation) em.createQuery("select o from ScoreCardRelation as o where o.scoreCard.idScoreCard = :idScoreCard and o.otherScoreCard.idScoreCard = :idOtherScoreCard").setParameter("idScoreCard", idScoreCard).setParameter("idOtherScoreCard", idOtherScoreCard).getSingleResult();
    }
    // Employee

    @Override
    public Employee findEmployee(Long idEmployee) {
        return (Employee) em.createQuery("select o from Employee as o where o.idEmployee = :idEmployee").setParameter("idEmployee", idEmployee).getSingleResult();
    }
    // Label

    @Override
    public Label findLabel(Long idLabel) {
        return (Label) em.createQuery("select o from Label as o where o.idLabel = :idLabel").setParameter("idLabel", idLabel).getSingleResult();
    }

    @Override
    public List<Label> findLabel(Project project) {
        return em.createQuery("select o from Label as o where o.project.idScoreCard = :idScoreCard").setParameter("idScoreCard", project.getIdScoreCard()).getResultList();
    }
    // Map

    @Override
    public Map findMap(Long idMap) {
        return (Map) em.createQuery("select o from Map as o where o.idScoreCard = :idMap").setParameter("idMap", idMap).getSingleResult();
    }

    @Override
    public List<Map> findMap() {
        return em.createQuery("select o from Map as o").getResultList();
    }
    // MapDrawingSettings

    @Override
    public MapDrawingSettings findMapDrawingSettings(Long idMapDrawingSettings) {
        return (MapDrawingSettings) em.createQuery("select o from MapDrawingSettings as o where o.idMapDrawingSettings = :idMapDrawingSettings" +
                " and o.mapDrawing.framework.active = :true").setParameter("true", true).setParameter("idMapDrawingSettings", idMapDrawingSettings).getSingleResult();
    }

    @Override
    public MapDrawingSettings findMapDrawingSettings(Settings settings, MapDrawing mapDrawing) {
        return (MapDrawingSettings) em.createQuery("select o from MapDrawingSettings as o where o.settings.idSettings = :idSettings and o.mapDrawing.idMapDrawing = :idMapDrawing" +
                " and o.mapDrawing.framework.active = :true").setParameter("idSettings", settings.getIdSettings()).setParameter("idMapDrawing", mapDrawing.getIdMapDrawing()).setParameter("true", true).getSingleResult();
    }

    @Override
    public List<MapDrawingSettings> findMapDrawingSettings(MapDrawing mapDrawing) {
        return em.createQuery("select o from MapDrawingSettings as o where o.mapDrawing.idMapDrawing = :idMapDrawing" +
                " and o.mapDrawing.framework.active = :true").setParameter("true", true).setParameter("idMapDrawing", mapDrawing.getIdMapDrawing()).getResultList();
    }

    @Override
    public List<MapDrawingSettings> findMapDrawingSettings(Settings settings) {
        return em.createQuery("select o from MapDrawingSettings as o where o.settings.idSettings = :idSettings").setParameter("idSettings", settings.getIdSettings()).getResultList();
    }

    // Milestone
    @Override
    public Milestone findMilestone(Long idMilestone) {
        return (Milestone) em.createQuery("select o from Task as o where o.idTask = :idMilestone").setParameter("idMilestone", idMilestone).getSingleResult();
    }

    @Override
    public List<Milestone> findMilestone(Project project) {
        return em.createQuery("select o from Milestone as o where o.project.idScoreCard = :idProject").setParameter("idProject", project.getIdScoreCard()).getResultList();
    }

    @Override
    public List<Milestone> findMilestone(Tracer tracer) {
        return em.createQuery("select o.milestone from MilestoneTracer as o where o.tracer.idTracer = :idTracer").setParameter("idTracer", tracer.getIdTracer()).getResultList();
    }
    // MilestoneTracer

    @Override
    public MilestoneTracer findMilestoneTracer(Long idMilestoneTracer) {
        return (MilestoneTracer) em.createQuery("select o from MilestoneTracer as o where o.idMilestoneTracer = :idMilestoneTracer").setParameter("idMilestoneTracer", idMilestoneTracer).getSingleResult();
    }

    @Override
    public MilestoneTracer findMilestoneTracer(Milestone milestone, Tracer tracer) {
        return (MilestoneTracer) em.createQuery("select o from MilestoneTracer as o where o.milestone.idTask = :idTask and o.tracer.idTracer = :idTracer").setParameter("idTask", milestone.getIdTask()).setParameter("idTracer", tracer.getIdTracer()).getSingleResult();
    }

    @Override
    public List<MilestoneTracer> findMilestoneTracer(Milestone milestone) {
        return em.createQuery("select o from MilestoneTracer as o where o.milestone.idTask = :idTask").setParameter("idTask", milestone.getIdTask()).getResultList();
    }
    // Note

    @Override
    public Note findNote(Long idNote) {
        return (Note) em.createQuery("select o from Note as o where o.idNote = :idNote").setParameter("idNote", idNote).getSingleResult();
    }

    @Override
    public List<Note> findNote(ScoreCard scoreCard) {
        return em.createQuery("select o from Note as o where o.scoreCard.idScoreCard = :idScoreCard").setParameter("idScoreCard", scoreCard.getIdScoreCard()).getResultList();
    }

    @Override
    public List<Note> findNote(Person person) {
        return em.createQuery("select o from Note as o where o.person.idPerson = :idPerson").setParameter("idPerson", person.getIdPerson()).getResultList();
    }
    // Objective

    @Override
    public Objective findObjective(Long idObjective) {
        return (Objective) em.createQuery("select o from Objective as o where o.idObjective = :idObjective").setParameter("idObjective", idObjective).getSingleResult();
    }
    // Person

    @Override
    public List<Person> findAvaliablePerson() {
        return em.createQuery("select o from Person as o where o.profile= :profileNormalUser").setParameter("profileNormalUser", Person.Profile.NORMAL_USER).getResultList();
    }

    @Override
    public List<Person> findPerson() {
        return em.createQuery("select o from Person as o").getResultList();
    }

    @Override
    public Person findPerson(Long idPerson) {
        return (Person) em.createQuery("select o from Person as o where o.idPerson = :idPerson").setParameter("idPerson", idPerson).getSingleResult();
    }

    @Override
    public List<Person> findPerson(ScoreDomain scoreDomain) {
        return em.createQuery("select o.person from PersonScoreDomain as o where o.scoreDomain.idScoreDomain = :idScoreDomain").setParameter("idScoreDomain", scoreDomain.getIdScoreDomain()).getResultList();
    }

    @Override
    public Person findPerson(String username, String password) {
        return (Person) em.createQuery("select o from Person as o where o.username = :username and o.password = :password").setParameter("username", username).setParameter("password", password).getSingleResult();
    }

    @Override
    public List<Person> findPerson(ScoreCard scoreCard) {
        return em.createQuery("select o.person from PersonScoreDomain as o where o.scoreDomain.idScoreDomain = :idScoreDomain").setParameter("idScoreCard", scoreCard.getIdScoreCard()).getResultList();
    }
    // PersonScoreDomain

    @Override
    public PersonScoreDomain findPersonScoreDomain(Person person, ScoreDomain scoreDomain) {
        return (PersonScoreDomain) em.createQuery("select o from PersonScoreDomain as o where o.person.idPerson = :idPerson and o.scoreDomain.idScoreDomain = :idScoreDomain").setParameter("idPerson", person.getIdPerson()).setParameter("idScoreDomain", scoreDomain.getIdScoreDomain()).getSingleResult();
    }

    @Override
    public List<PersonScoreDomain> findPersonScoreDomain(Person person) {
        return em.createQuery("select o from PersonScoreDomain as o where o.person.idPerson = :idPerson").setParameter("idPerson", person.getIdPerson()).getResultList();
    }

    @Override
    public List<PersonScoreDomain> findPersonScoreDomain(ScoreDomain scoreDomain) {
        return em.createQuery("select o from PersonScoreDomain as o where o.scoreDomain.idScoreDomain = :idScoreDomain").setParameter("idScoreDomain", scoreDomain.getIdScoreDomain()).getResultList();
    }
    // PersonScoreCard

    @Override
    public PersonScoreCard findPersonScoreCard(Long idPersonScoreCard) {
        return (PersonScoreCard) em.createQuery("select o from PersonScoreCard as o where o.idPersonScoreCard = :idPersonScoreCard").setParameter("idPersonScoreCard", idPersonScoreCard).getSingleResult();
    }

    @Override
    public PersonScoreCard findPersonScoreCard(Person person, ScoreCard scoreCard) {
        return (PersonScoreCard) em.createQuery("select o from PersonScoreCard as o where o.person.idPerson = :idPerson and o.scoreCard = :idScoreCard").setParameter("idPerson", person.getIdPerson()).setParameter("idScoreCard", scoreCard.getIdScoreCard()).getSingleResult();
    }

    @Override
    public List<PersonScoreCard> findPersonScoreCard(Person person) {
        return em.createQuery("select o from PersonScoreCard as o where o.person.idPerson = :idPerson").setParameter("idPerson", person.getIdPerson()).getResultList();
    }

    @Override
    public List<PersonScoreCard> findPersonScoreCard(ScoreCard scoreCard) {
        return em.createQuery("select o from PersonScoreCard as o where o.scoreCard.idScoreCard = :idScoreCard").setParameter("idScoreCard", scoreCard.getIdScoreCard()).getResultList();
    }
    // Perspective

    @Override
    public Perspective findPerspective(Long idPerspective) {
        return (Perspective) em.createQuery("select o from Perspective as o where o.idPerspective = :idPerspective").setParameter("idPerspective", idPerspective).getSingleResult();
    }
    // Pointer

    @Override
    public Pointer findPointer(Long idPointer) {
        return (Pointer) em.createQuery("select o from Pointer as o where o.idPointer = :idPointer").setParameter("idPointer", idPointer).getSingleResult();
    }
    // Project

    @Override
    public List<Project> findProject() {
        return em.createQuery("select o from Project as o").getResultList();
    }

    @Override
    public Project findProject(Long idProject) {
        return (Project) em.createQuery("select o from Project as o where o.idScoreCard = :idProject").setParameter("idProject", idProject).getSingleResult();
    }

    @Override public List<Project> findProject(Person person){
        return em.createQuery("select o from Project as o where o.responsible.idPerson = :idPerson")
                .setParameter("idPerson",person.getIdPerson())
                .getResultList();
    }
    // SRM

    @Override
    public List<SRM> findSRM() {
        return em.createQuery("select o from SRM as o order by o.SRMDate").getResultList();
    }

    @Override
    public SRM findSRM(Long idSRM) {
        return (SRM) em.createQuery("select o from SRM as o where o.idSRM = :idSRM").setParameter("idSRM", idSRM).getSingleResult();
    }

    @Override
    public List<SRM> findSRM(ScoreView scoreView) {
        return em.createQuery("select o.person from SRM as o where o.scoreView.idScoreView = :idScoreView").setParameter("idScoreView", scoreView.getIdScoreView()).getResultList();
    }

    @Override
    public List<SRM> findSRM(Topic topic) {
        return em.createQuery("select o.SRM from SRMTopic as o where o.topic.idTopic = :idTopic").setParameter("idTopic", topic.getIdTopic()).getResultList();
    }
    // SRMTopic

    @Override
    public SRMTopic findSRMTopic(Long idSRMTopic) {
        return (SRMTopic) em.createQuery("select o from SRMTopic as o where o.idSRMTopic = :idSRMTopic").setParameter("idSRMTopic", idSRMTopic).getSingleResult();
    }

    @Override
    public List<SRMTopic> findSRMTopic(SRM SRM) {
        return em.createQuery("select o from SRMTopic as o where o.SRM.idSRM = :idSRM").setParameter("idSRM", SRM.getIdSRM()).getResultList();
    }

    @Override
    public List<SRMTopic> findSRMTopic(Topic topic) {
        return em.createQuery("select o from SRMTopic as o where o.Topic.idTopic = :idTopic").setParameter("idTopic", topic.getIdTopic()).getResultList();
    }

    @Override
    public SRMTopic findSRMTopic(SRM SRM, Topic topic) {
        return (SRMTopic) em.createQuery("select o from SRMTopic as o where o.SRM.idSRM = :idSRM and o.topic.idTopic = :idTopic").setParameter("idSRM", SRM.getIdSRM()).setParameter("idTopic", topic.getIdTopic()).getSingleResult();
    }
    // ScoreCard

    @Override
    public List<ScoreCard> findScoreCard() {
        return em.createQuery("select o from ScoreCard as o").getResultList();
    }

    @Override
    public ScoreCard findScoreCard(Long idScoreCard) {
        return (ScoreCard) em.createQuery("select o from ScoreCard as o where o.idScoreCard = :idScoreCard").setParameter("idScoreCard", idScoreCard).getSingleResult();
    }

    @Override
    public List<ScoreCard> findScoreCard(ScoreDomain scoreDomain) {
        return em.createQuery("select o from ScoreCardDomain as o where o.scoreDomain.idScoreDomain = :idScoreDomain").setParameter("idScoreDomain", scoreDomain.getIdScoreDomain()).getResultList();
    }

    @Override
    public List<ScoreCard> findScoreCard(ScoreCard scoreCard) {
        return em.createQuery("select o.otherScoreCard from ScoreCardRelation as o where o.scoreCard.idScoreCard = :idScoreCard").setParameter("idScoreCard", scoreCard.getIdScoreCard()) // .setParameter("idOtherScoreCard",scoreCard.getIdScoreCard())
                .getResultList();
    }

    @Override
    public List<ScoreCard> findOtherScoreCards(Long idScoreCard) {
        return em.createQuery("select o.otherScoreCard from ScoreCardRelation as o where o.scoreCard.idScoreCard = :idScoreCard").setParameter("idScoreCard", idScoreCard).getResultList();
    }

    @Override
    public List<ScoreCard> findOtherScoreCardsRevert(Long idScoreCard) {
        return em.createQuery("select o.scoreCard from ScoreCardRelation as o where o.otherScoreCard.idScoreCard = :idScoreCard").setParameter("idScoreCard", idScoreCard).getResultList();
    }
    // ScoreView

    @Override
    public List<ScoreView> findScoreView() {
        return em.createQuery("select o from ScoreView as o").getResultList();
    }

    @Override
    public ScoreView findScoreView(Long idScoreView) {
        return (ScoreView) em.createQuery("select o from ScoreView as o where o.idScoreView = :idScoreView").setParameter("idScoreView", idScoreView).getSingleResult();
    }

    @Override
    public List<ScoreView> findScoreView(Topic topic) {
        return em.createQuery("select o.scoreView from TopicScoreView as o where o.topic.idTopic = :idTopic").setParameter("idTopic", topic.getIdTopic()).getResultList();
    }
    // Settings

    @Override
    public Settings findSettings(Long idSettings) {
        return (Settings) em.createQuery("select o from Settings as o where o.idSettings = :idSettings").setParameter("idSettings", idSettings).getSingleResult();
    }
    // Task

    @Override
    public Task findTask(Long idTask) {
        return (Task) em.createQuery("select o from Task as o where o.idTask = :idTask").setParameter("idTask", idTask).getSingleResult();
    }

    @Override
    public List<Task> findTask(Project project) {
        return em.createQuery("select o from Task as o where o.project.idScoreCard = :idProject").setParameter("idProject", project.getIdScoreCard()).getResultList();
    }

    @Override
    public List<Task> findTask(Task task) {
        return em.createQuery("select o from Task as o where o.task.idTask = :idTask").setParameter("idTask", task.getIdTask()).getResultList();
    }

    @Override
    public Task findRootTask(Project project) {
        return (Task) em.createQuery("select o from Task as o where o.project.idScoreCard = :idScoreCard and o.root = :true").setParameter("idScoreCard", project.getIdScoreCard()).setParameter("true", true).getSingleResult();
    }

    // Theme
    @Override
    public Theme findTheme(Long idTheme) {
        return (Theme) em.createQuery("select o from Theme as o where o.idTheme = :idTheme").setParameter("idTheme", idTheme).getSingleResult();
    }
    // Topic

    @Override
    public Topic findTopic(Long idTopic) {
        return (Topic) em.createQuery("select o from Topic as o where o.idTopic = :idTopic").setParameter("idTopic", idTopic).getSingleResult();
    }

    @Override
    public List<Topic> findTopic(ScoreView scoreView) {
        return em.createQuery("select o.topic from TopicScoreView as o where o.scoreView.idScoreView = :idScoreView").setParameter("idScoreView", scoreView.getIdScoreView()).getResultList();
    }

    @Override
    public List<Topic> findTopic(SRM SRM) {
        return em.createQuery("select o.topic from SRMTopic as o where o.SRM.idSRM = :idSRM").setParameter("idSRM", SRM.getIdSRM()).getResultList();
    }

    @Override
    public List<Topic> findTopic(ScoreCard scoreCard) {
        return em.createQuery("select o from Topic as o where o.scoreCard.idScoreCard = :idScoreCard").setParameter("idScoreCard", scoreCard.getIdScoreCard()).getResultList();
    }

    @Override
    public List<Topic> findTopicsView(ScoreView scoreView) {
        return em.createQuery("select o.topic from TopicScoreView as o where o.scoreView.idScoreView = :idScoreView and o.type != :type").setParameter("idScoreView", scoreView.getIdScoreView()).setParameter("type", TopicScoreView.Type.COMPLETED).getResultList();
    }
    // TopicScoreView

    @Override
    public TopicScoreView findTopicScoreView(Topic topic, ScoreView scoreView) {
        return (TopicScoreView) em.createQuery("select o from TopicScoreView as o where o.topic.idTopic = :idTopic and o.scoreView.idScoreView = :idScoreView").setParameter("idTopic", topic.getIdTopic()).setParameter("idScoreView", scoreView.getIdScoreView()).getSingleResult();
    }

    // TopicScoreView
    @Override
    public List<TopicScoreView> findTopicScoreView(Topic topic) {
        return em.createQuery("select o from TopicScoreView as o where o.topic.idTopic = :idTopic").setParameter("idTopic", topic.getIdTopic()).getResultList();
    }

    @Override
    public List<TopicScoreView> findTopicScoreView(ScoreView scoreView) {
        return em.createQuery("select o from TopicScoreView as o where o.scoreView.idScoreView = :idScoreView").setParameter("idScoreView", scoreView.getIdScoreView()).getResultList();
    }

    // Tracer
    @Override
    public Tracer findTracer(Long idTracer) {
        return (Tracer) em.createQuery("select o from Tracer as o where o.idTracer = :idTracer").setParameter("idTracer", idTracer).getSingleResult();
    }

    @Override
    public List<Tracer> findTracer(Milestone milestone) {
        return em.createQuery("select o.tracer from MilestoneTracer as o where o.milestone.idMilestone = :idMilestone").setParameter("idMilestone", milestone.getIdTask()).getResultList();
    }

    @Override
    public List<Tracer> findTracer(Project project) {
        return em.createQuery("select o from Tracer as o where o.project.idScoreCard = :idScoreCard").setParameter("idScoreCard", project.getIdScoreCard()).getResultList();
    }

    @Override
    public Tracer findTracer(Project project, Tracer.Type type) {
        return (Tracer) em.createQuery("select o from Tracer as o where o.project.idScoreCard = :idScoreCard and o.type = :type").setParameter("idScoreCard", project.getIdScoreCard()).setParameter("type", type).getSingleResult();
    }
    // create

    @Override
    public void createArea(Area area) {
        em.persist(area);
    }

    @Override
    public void createAttachment(Attachment attachment) {
        em.persist(attachment);
    }

    @Override
    public void createColorimetrySettings(ColorimetrySettings colorimetrySettings) {
        em.persist(colorimetrySettings);
    }

    @Override
    public void createComparator(Comparator comparator) {
        em.persist(comparator);
    }

    @Override
    public void createComparatorDimensionalCut(ComparatorDimensionalCut comparatorDimensionalCut) {
        em.persist(comparatorDimensionalCut);
    }

    @Override
    public void createDimension(Dimension dimension) {
        em.persist(dimension);
    }

    @Override
    public void createDimensionMember(DimensionMember dimensionMember) {
        em.persist(dimensionMember);
    }

    @Override
    public void createDimensionalCut(DimensionalCut dimensionalCut) {
        em.persist(dimensionalCut);
    }

    @Override
    public void createDimensionalCutMember(DimensionalCutMember dimensionalCutMember) {

        em.persist(dimensionalCutMember);
    }

    @Override
    public void createEmployee(Employee employee) {
        em.persist(employee);
    }

    @Override
    public void createLabel(Label label) {
        em.persist(label);
    }

    @Override
    public void createMap(Map map) {
        em.persist(map);
    }

    @Override
    public void createMilestone(Milestone milestone) {
        em.persist(milestone);
    }

    @Override
    public void createMilestoneTracer(MilestoneTracer milestoneTracer) {
        em.persist(milestoneTracer);
    }

    @Override
    public void createNote(Note note) {
        em.persist(note);
    }

    @Override
    public void createObjective(Objective objective) {
        em.persist(objective);
    }

    @Override
    public void createPerson(Person person) {
        em.persist(person);
    }

    @Override
    public void createPersonScoreCard(PersonScoreCard personScoreCard) {
        em.persist(personScoreCard);
    }

    @Override
    public void createPersonScoreDomain(PersonScoreDomain personScoreDomain) {
        em.persist(personScoreDomain);
    }

    @Override
    public void createPerspective(Perspective perspective) {
        em.persist(perspective);
    }

    @Override
    public void createPointer(Pointer pointer) {
        em.persist(pointer);
    }

    @Override
    public void createProject(Project project) {
        em.persist(project);
    }

    @Override
    public void createSRM(SRM SRM) {
        em.persist(SRM);
    }

    @Override
    public void createSRMTopic(SRMTopic SRMTopic) {
        em.persist(SRMTopic);
    }

    @Override
    public void createScoreCard(ScoreCard scoreCard) {
        em.persist(scoreCard);
    }

    @Override
    public void createScoreCardDimension(ScoreCardDimension scoreCardDimension) {
        em.persist(scoreCardDimension);
    }

    @Override
    public void createScoreCardDomain(ScoreCardDomain scoreCardDomain) {
        em.persist(scoreCardDomain);
    }

    @Override
    public void createScoreCardRelation(ScoreCardRelation scoreCardRelation) {
        em.persist(scoreCardRelation);
    }

    @Override
    public void createScoreDomain(ScoreDomain scoreDomain) {
        em.persist(scoreDomain);
    }

    @Override
    public void createScoreView(ScoreView scoreView) {
        em.persist(scoreView);
    }

    @Override
    public void createSettings(Settings settings) {
        em.persist(settings);
    }

    @Override
    public void createTask(Task task) {
        em.persist(task);
    }

    @Override
    public void createTheme(Theme theme) {
        em.persist(theme);
    }

    @Override
    public void createTopic(Topic topic) {
        em.persist(topic);
    }

    @Override
    public void createTopicScoreView(TopicScoreView topicScoreView) {
        em.persist(topicScoreView);
    }

    @Override
    public void createTracer(Tracer tracer) {
        em.persist(tracer);
    }

    // update
    @Override
    public void updateArea(Area area) {
        em.merge(area);
    }

    @Override
    public void updateAttachment(Attachment attachment) {
        em.merge(attachment);
    }

    @Override
    public void updateColorimetrySettings(ColorimetrySettings colorimetrySettings) {
        em.merge(colorimetrySettings);
    }

    @Override
    public void updateComparator(Comparator comparator) {
        em.merge(comparator);
    }

    @Override
    public void updateComparatorDimensionalCut(ComparatorDimensionalCut comparatorDimensionalCut) {
        em.merge(comparatorDimensionalCut);
    }

    @Override
    public void updateDimension(Dimension dimension) {
        em.merge(dimension);
    }

    @Override
    public void updateDimensionMember(DimensionMember dimensionMember) {
        em.merge(dimensionMember);
    }

    @Override
    public void updateDimensionalCut(DimensionalCut dimensionalCut) {
        em.merge(dimensionalCut);
    }

    @Override
    public void updateDimensionalCutMember(DimensionalCutMember dimensionalCutMember) {
        em.merge(dimensionalCutMember);
    }

    @Override
    public void updateDomain(ScoreDomain domain) {
        em.merge(domain);
    }

    @Override
    public void updateEmployee(Employee employee) {
        em.merge(employee);
    }

    @Override
    public void updateLabel(Label label) {
        em.merge(label);
    }

    @Override
    public void updateMap(Map map) {
        em.merge(map);
    }

    @Override
    public void updateMilestone(Milestone milestone) {
        em.merge(milestone);
    }

    @Override
    public void updateMilestoneTracer(MilestoneTracer milestoneTracer) {
        em.merge(milestoneTracer);
    }

    @Override
    public void updateNote(Note note) {
        em.merge(note);
    }

    @Override
    public void updateObjective(Objective objective) {
        em.merge(objective);
    }

    @Override
    public void updatePerson(Person person) {
        em.merge(person);
    }

    @Override
    public void updatePersonScoreCard(PersonScoreCard personScoreCard) {
        em.merge(personScoreCard);
    }

    @Override
    public void updatePersonScoreDomain(PersonScoreDomain personScoreDomain) {
        em.merge(personScoreDomain);
    }

    @Override
    public void updatePerspective(Perspective perspective) {
        em.merge(perspective);
    }

    @Override
    public void updatePointer(Pointer pointer) {
        em.merge(pointer);
    }

    @Override
    public void updateProject(Project project) {
        em.merge(project);
    }

    @Override
    public void updateSRM(SRM SRM) {
        em.merge(SRM);
    }

    @Override
    public void updateSRMTopic(SRMTopic SRMTopic) {
        em.merge(SRMTopic);
    }

    @Override
    public void updateScoreCard(ScoreCard scoreCard) {
        em.merge(scoreCard);
    }

    @Override
    public void updateScoreCardDimension(ScoreCardDimension scoreCardDimension) {
        em.merge(scoreCardDimension);
    }

    @Override
    public void updateScoreCardDomain(ScoreCardDomain scoreCardDomain) {
        em.merge(scoreCardDomain);
    }

    @Override
    public void updateScoreCardRelation(ScoreCardRelation scoreCardRelation) {
        em.merge(scoreCardRelation);
    }

    @Override
    public void updateScoreDomain(ScoreDomain scoreDomain) {
        em.merge(scoreDomain);
    }

    @Override
    public void updateScoreView(ScoreView scoreView) {
        em.merge(scoreView);
    }

    @Override
    public void updateSettings(Settings settings) {
        em.merge(settings);
    }

    @Override
    public void updateTask(Task task) {
        em.merge(task);
    }

    @Override
    public void updateTheme(Theme theme) {
        em.merge(theme);
    }

    @Override
    public void updateTopic(Topic topic) {
        em.merge(topic);
    }

    @Override
    public void updateTopicScoreView(TopicScoreView topicScoreView) {
        em.merge(topicScoreView);
    }

    @Override
    public void updateTracer(Tracer tracer) {
        em.merge(tracer);
    }
    
    @Override
    public void deleteArea(Area area) {
        em.remove(em.merge(area));
    }

    @Override
    public void deleteAttachment(Attachment attachment) {
        em.remove(em.merge(attachment));
    }

    @Override
    public void deleteComparator(Comparator comparator) {
        em.remove(em.merge(comparator));
    }

    @Override
    public void deleteComparatorDimensionalCut(ComparatorDimensionalCut comparatorDimensionalCut) {
        em.remove(em.merge(comparatorDimensionalCut));
    }

    @Override
    public void deleteDimension(Dimension dimension) {
        em.remove(em.merge(dimension));
    }

    @Override
    public void deleteDimensionMember(DimensionMember dimensionMember) {
        em.remove(em.merge(dimensionMember));
    }

    @Override
    public void deleteDimensionalCut(DimensionalCut dimensionalCut) {
        em.remove(em.merge(dimensionalCut));
    }

    @Override
    public void deleteDimensionalCutMember(DimensionalCutMember dimensionalCutMember) {
        em.remove(em.merge(dimensionalCutMember));
    }

    @Override
    public void deleteDomain(ScoreDomain domain) {
        em.remove(em.merge(domain));
    }

    @Override
    public void deleteEmployee(Employee employee) {
        em.remove(em.merge(employee));
    }

    @Override
    public void deleteLabel(Label label) {
        em.remove(em.merge(label));
    }

    @Override
    public void deleteMap(Map map) {
        em.remove(em.merge(map));
    }

    @Override
    public void deleteMilestone(Milestone milestone) {
        em.remove(em.merge(milestone));
    }

    @Override
    public void deleteMilestoneTracer(MilestoneTracer milestoneTracer) {
        em.remove(em.merge(milestoneTracer));
    }

    @Override
    public void deleteNote(Note note) {
        em.remove(em.merge(note));
    }

    @Override
    public void deleteObjective(Objective objective) {
        em.remove(em.merge(objective));
    }

    @Override
    public void deletePerson(Person person) {
        em.remove(em.merge(person));
    }

    @Override
    public void deletePersonScoreCard(PersonScoreCard personScoreCard) {
        em.remove(em.merge(personScoreCard));
    }

    @Override
    public void deletePersonScoreDomain(PersonScoreDomain personScoreDomain) {
        em.remove(em.merge(personScoreDomain));
    }

    @Override
    public void deletePerspective(Perspective perspective) {
        em.remove(em.merge(perspective));
    }

    @Override
    public void deletePointer(Pointer pointer) {
        em.remove(em.merge(pointer));
    }

    @Override
    public void deleteProject(Project project) {
        em.remove(em.merge(project));
    }

    @Override
    public void deleteSRM(SRM SRM) {
        em.remove(em.merge(SRM));
    }

    @Override
    public void deleteSRMTopic(SRMTopic SRMTopic) {
        em.remove(em.merge(SRMTopic));
    }

    @Override
    public void deleteScoreCard(ScoreCard scoreCard) {
        em.remove(em.merge(scoreCard));
    }

    @Override
    public void deleteScoreCardDimension(ScoreCardDimension scoreCardDimension) {
        em.remove(em.merge(scoreCardDimension));
    }

    @Override
    public void deleteScoreCardDomain(ScoreCardDomain scoreCardDomain) {
        em.remove(em.merge(scoreCardDomain));
    }

    @Override
    public void deleteScoreCardRelation(ScoreCardRelation scoreCardRelation) {
        em.remove(em.merge(scoreCardRelation));
    }

    @Override
    public void deleteScoreDomain(ScoreDomain scoreDomain) {
        em.remove(em.merge(scoreDomain));
    }

    @Override
    public void deleteScoreView(ScoreView scoreView) {
        em.remove(em.merge(scoreView));
    }

    @Override
    public void deleteSettings(Settings settings) {
        em.remove(em.merge(settings));
    }

    @Override
    public void deleteTask(Task task) {
        em.remove(em.merge(task));
    }

    @Override
    public void deleteTheme(Theme theme) {
        em.remove(em.merge(theme));
    }

    @Override
    public void deleteTopic(Topic topic) {
        em.remove(em.merge(topic));
    }

    @Override
    public void deleteTopicScoreView(TopicScoreView topicScoreView) {
        em.remove(em.merge(topicScoreView));
    }

    @Override
    public void deleteTracer(Tracer tracer) {
        em.remove(em.merge(tracer));
    }

    /**
     * <METADATA>
     */
    // Activity
    @Override
    public Activity findActivity(Long idActivity) {
        return (Activity) em.createQuery("select o from Activity as o where o.idActivity = :idActivity").setParameter("idActivity", idActivity).getSingleResult();
    }
    // Alert

    @Override
    public Alert findAlert(Long idAlert) {
        return (Alert) em.createQuery("select o from Alert as o where o.idAlert = :idAlert").setParameter("idAlert", idAlert).getSingleResult();
    }

    @Override
    public List<Alert> findAlert(Framework framework) {
        return em.createQuery("select o from Alert as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
    }

    // Colorimetry
    @Override
    public Colorimetry findColorimetry(Long idColorimetry) {
        return (Colorimetry) em.createQuery("select o from Colorimetry as o where o.idColorimetry = :idColorimetry").setParameter("idColorimetry", idColorimetry).getSingleResult();
    }

    @Override
    public List<Colorimetry> findColorimetry(Framework framework, Boolean frameworkMember) {
        if (frameworkMember) {
            return em.createQuery("select o from Colorimetry as o where o.framework.idFramework = :idFramework order by o.priority").setParameter("idFramework", framework.getIdFramework()).getResultList();
        } else {
            return em.createQuery("select o from Colorimetry as o where o.framework.idFramework != :idFramework order by o.priority").setParameter("idFramework", framework.getIdFramework()).getResultList();
        }

    }

    @Override
    public Colorimetry findColorimetry(ScoreCard scoreCard, Double score) {
        if (score == null || score.isNaN()) {
            return null;
        }
        return (Colorimetry) em.createQuery("select o.colorimetry from ColorimetrySettings as o where o.settings.idSettings = :idSettings " +
                "and o.minScore <= :score and o.maxScore > :score and o.colorimetry.framework.active = :true").setParameter("true", true).setParameter("score", score).setParameter("idSettings", scoreCard.getSettings().getIdSettings()).getSingleResult();
    }

    @Override
    public ColorimetrySettings findColorimetrySettings(Colorimetry colorimetry, Settings settings) {
        return (ColorimetrySettings) em.createQuery("select o from ColorimetrySettings as o where o.settings.idSettings = :idSettings " +
                "and o.colorimetry.idColorimetry = :idColorimetry").setParameter("idColorimetry", colorimetry.getIdColorimetry()).setParameter("idSettings", settings.getIdSettings()).getSingleResult();
    }

    @Override
    public List<ColorimetrySettings> findColorimetrySettings(ScoreCard scoreCard) {
        return em.createQuery("select o from ColorimetrySettings as o where o.settings.idSettings = :idSettings " +
                "and o.colorimetry.framework.active = :true order by o.colorimetry.priority").setParameter("true", true).setParameter("idSettings", scoreCard.getSettings().getIdSettings()).getResultList();
    }

    @Override
    public List<ColorimetrySettings> findColorimetrySettings(Colorimetry colorimetry) {
        return em.createQuery("select o from ColorimetrySettings as o where o.colorimetry.idColorimetry = :idColorimetry").setParameter("idColorimetry", colorimetry.getIdColorimetry()).getResultList();
    }

    @Override
    public List<ColorimetrySettings> findColorimetrySettings(Settings settings) {
        return em.createQuery("select o from ColorimetrySettings as o where o.settings.idSettings = :idSettings").setParameter("idSettings", settings.getIdSettings()).getResultList();
    }

    @Override
    public List<Colorimetry> findColorimetry() {
        return em.createQuery("select o from Colorimetry as o").getResultList();
    }
    // Comparation

    @Override
    public Comparation findComparation(Long idComparation) {
        return (Comparation) em.createQuery("select o from Comparation as o where o.idComparation = :idComparation").setParameter("idComparation", idComparation).getSingleResult();
    }

    @Override
    public Comparation findComparation(Framework framework, Comparation.Type type) {
        return (Comparation) em.createQuery("select o from Comparation as o where o.framework.idFramework = :idFramework and o.type = :type").setParameter("idFramework", framework.getIdFramework()).setParameter("type", type).getSingleResult();
    }

    @Override
    public List<Comparation> findComparation(Framework framework, Boolean frameworkMember) {
        if (frameworkMember) {
            return em.createQuery("select o from Comparation as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        } else {
            return em.createQuery("select o from Comparation as o where o.framework.idFramework != :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        }
    }
    // Formula

    @Override
    public Formula findFormula(Long idFormula) {
        return (Formula) em.createQuery("select o from Formula as o where o.idFormula = :idFormula").setParameter("idFormula", idFormula).getSingleResult();
    }

    @Override
    public List<Formula> findFormula(Framework framework) {
        return em.createQuery("select o from Formula as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
    }
    // Framework

    @Override
    public Framework findFramework(Long idFramework) {
        return (Framework) em.createQuery("select o from Framework as o where o.idFramework = :idFramework").setParameter("idFramework", idFramework).getSingleResult();
    }

    @Override
    public Framework findFramework(Boolean active) {
        return (Framework) em.createQuery("select o from Framework as o where o.active = :active").setParameter("active", active).getSingleResult();
    }

    @Override
    public List<Framework> findFramework() {
        return em.createQuery("select o from Framework as o ").getResultList();
    }
    // Graph

    @Override
    public Graph findGraph(Long idGraph) {
        return (Graph) em.createQuery("select o from Graph as o where o.idGraph = :idGraph").setParameter("idGraph", idGraph).getSingleResult();
    }

    @Override
    public List<Graph> findGraph(Framework framework) {
        return em.createQuery("select o from Graph as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
    }
    // Icon

    @Override
    public Icon findIcon(Long idIcon) {
        return (Icon) em.createQuery("select o from Icon as o where o.idIcon = :idIcon").setParameter("idIcon", idIcon).getSingleResult();
    }

    @Override
    public List<Icon> findIcon(Colorimetry colorimetry) {
        return em.createQuery("select o.icon from ColorimetryIcon as o where o.colorimetry.idColorimetry= :idColorimetry").setParameter("idColorimetry", colorimetry.getIdColorimetry()).getResultList();
    }
    // Lang

    @Override
    public Lang findLang(Long idLang) {
        return (Lang) em.createQuery("select o from Lang as o where o.idLang = :idLang").setParameter("idLang", idLang).getSingleResult();
    }

    @Override
    public List<Lang> findLang(Framework framework, Boolean frameworkMember) {
        if (frameworkMember) {
            return em.createQuery("select o from Lang as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        } else {
            return em.createQuery("select o from Lang as o where o.framework.idFramework != :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        }
    }

    @Override
    public List<Lang> findLang() {
        return em.createQuery("select o from Lang as o").getResultList();
    }
    // License

    @Override
    public License findLicense(Long idLicense) {
        return (License) em.createQuery("select o from License as o where o.idLicense = :idLicense").setParameter("idLicense", idLicense).getSingleResult();
    }

    @Override
    public License findCurrentLicense() {
        return (License) em.createQuery("select o from License as o order by o.idLicense desc").setMaxResults(1).getResultList().get(0);
    }

    @Override
    public List<License> findLicense() {
        return em.createQuery("select o from License as o").getResultList();
    }
    // MapDrawing

    @Override
    public MapDrawing findMapDrawing(Long idMapDrawing) {
        return (MapDrawing) em.createQuery("select o from MapDrawing as o where o.idMapDrawing = :idMapDrawing").setParameter("idMapDrawing", idMapDrawing).getSingleResult();
    }

    @Override
    public List<MapDrawing> findMapDrawing(Framework framework, Boolean frameworkMember) {
        if (frameworkMember) {
            return em.createQuery("select o from MapDrawing as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        } else {
            return em.createQuery("select o from MapDrawing as o where o.framework.idFramework != :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        }
    }

    @Override
    public List<MapDrawing> findMapDrawing() {
        return em.createQuery("select o from MapDrawing as o").getResultList();
    }
    // NoteType

    @Override
    public NoteType findNoteType(Long idNoteType) {
        return (NoteType) em.createQuery("select o from NoteType as o where o.idNoteType = :idNoteType").setParameter("idNoteType", idNoteType).getSingleResult();
    }

    @Override
    public List<NoteType> findNoteType(Framework framework, Boolean frameworkMember) {
        if (frameworkMember) {
            return em.createQuery("select o from NoteType as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        } else {
            return em.createQuery("select o from NoteType as o where o.framework.idFramework != :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        }
    }

    @Override
    public List<NoteType> findNoteType() {
        return em.createQuery("select o from NoteType as o").getResultList();
    }
    // Profile

    @Override
    public Profile findProfile(Long idProfile) {
        return (Profile) em.createQuery("select o from Profile as o where o.idProfile = :idProfile").setParameter("idProfile", idProfile).getSingleResult();
    }
    // SMTP

    @Override
    public SMTP findSMTP(Long idSMTP) {
        return (SMTP) em.createQuery("select o from SMTP as o where o.idSMTP = :idSMTP").setParameter("idSMTP", idSMTP).getSingleResult();
    }

    @Override
    public SMTP findSMTP(Framework framework) {
        return (SMTP) em.createQuery("select o from SMTP as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getSingleResult();
    }

    @Override
    public List<SMTP> findSMTP(Framework framework, Boolean frameworkMember) {

        if (frameworkMember) {
            return em.createQuery("select o from SMTP as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        } else {
            return em.createQuery("select o from SMTP as o where o.framework.idFramework != :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        }
    }

    @Override
    public List<Profile> findProfile(Framework framework) {
        return em.createQuery("select o from Profile as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
    }
    // TimePeriod

    @Override
    public TimePeriod findTimePeriod(Long idTimePeriod) {
        return (TimePeriod) em.createQuery("select o from TimePeriod as o where o.idTimePeriod = :idTimePeriod").setParameter("idTimePeriod", idTimePeriod).getSingleResult();
    }

    @Override
    public List<TimePeriod> findTimePeriod(Framework framework) {
        return em.createQuery("select o from TimePeriod as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
    }
    // Unit

    @Override
    public Unit findUnit(Long idUnit) {
        return (Unit) em.createQuery("select o from Unit as o where o.idUnit = :idUnit").setParameter("idUnit", idUnit).getSingleResult();
    }

    @Override
    public List<Unit> findUnit(Framework framework, Boolean frameworkMember) {
        if (frameworkMember) {
            return em.createQuery("select o from Unit as o where o.framework.idFramework = :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        } else {
            return em.createQuery("select o from Unit as o where o.framework.idFramework != :idFramework").setParameter("idFramework", framework.getIdFramework()).getResultList();
        }
    }

    @Override
    public List<Unit> findUnit() {
        return em.createQuery("select o from Unit as o").getResultList();
    }

    // create
    public void createActionPlan(ActionPlan actionPlan) {
        em.persist(actionPlan);
    }

    @Override
    public void createActivity(Activity activity) {
        em.persist(activity);
    }

    @Override
    public void createAlert(Alert alert) {
        em.persist(alert);
    }

    @Override
    public void createColorimetry(Colorimetry colorimetry) {
        em.persist(colorimetry);
    }

    @Override
    public void createComparation(Comparation comparation) {
        em.persist(comparation);
    }

    @Override
    public void createFormula(Formula formula) {
        em.persist(formula);
    }

    @Override
    public void createFramework(Framework framework) {
        em.persist(framework);
    }

    @Override
    public void createGraph(Graph graph) {
        em.persist(graph);
    }

    @Override
    public void createIcon(Icon icon) {
        em.persist(icon);
    }

    @Override
    public void createLang(Lang lang) {
        em.persist(lang);
    }

    @Override
    public void createLicense(License license) {
        em.persist(license);
    }

    @Override
    public void createMapDrawing(MapDrawing mapDrawing) {
        em.persist(mapDrawing);
    }

    @Override
    public void createMapDrawingSettings(MapDrawingSettings mapDrawingSettings) {
        em.persist(mapDrawingSettings);
    }

    @Override
    public void createNoteType(NoteType noteType) {
        em.persist(noteType);
    }

    @Override
    public void createProfile(Profile profile) {
        em.persist(profile);
    }

    @Override
    public void createSMTP(SMTP SMTP) {
        em.persist(SMTP);
    }

    @Override
    public void createTimePeriod(TimePeriod timePeriod) {
        em.persist(timePeriod);
    }

    @Override
    public void createUnit(Unit unit) {
        em.persist(unit);
    }

    // update



    @Override
    public void updateActivity(Activity activity) {
        em.merge(activity);
    }

    @Override
    public void updateAlert(Alert alert) {
        em.merge(alert);
    }

    @Override
    public void updateColorimetry(Colorimetry colorimetry) {
        em.merge(colorimetry);
    }

    @Override
    public void updateComparation(Comparation comparation) {
        em.merge(comparation);
    }

    @Override
    public void updateFormula(Formula formula) {
        em.merge(formula);
    }

    @Override
    public void updateFramework(Framework framework) {
        em.merge(framework);
    }

    @Override
    public void updateGraph(Graph graph) {
        em.merge(graph);
    }

    @Override
    public void updateIcon(Icon icon) {
        em.merge(icon);
    }

    @Override
    public void updateLang(Lang lang) {
        em.merge(lang);
    }

    @Override
    public void updateLicense(License license) {
        em.merge(license);
    }

    @Override
    public void updateMapDrawing(MapDrawing mapDrawing) {
        em.merge(mapDrawing);
    }

    @Override
    public void updateMapDrawingSettings(MapDrawingSettings mapDrawingSettings) {
        em.merge(mapDrawingSettings);
    }

    @Override
    public void updateNoteType(NoteType noteType) {
        em.merge(noteType);
    }

    @Override
    public void updateProfile(Profile profile) {
        em.merge(profile);
    }

    @Override
    public void updateSMTP(SMTP SMTP) {
        em.merge(SMTP);
    }

    @Override
    public void updateTimePeriod(TimePeriod timePeriod) {
        em.merge(timePeriod);
    }

    @Override
    public void updateUnit(Unit unit) {
        em.merge(unit);
    }

    // delete
    @Override
    public void deleteActivity(Activity activity) {
        em.remove(em.merge(activity));
    }

    @Override
    public void deleteAlert(Alert alert) {
        em.remove(em.merge(alert));
    }

    @Override
    public void deleteColorimetry(Colorimetry colorimetry) {
        em.remove(em.merge(colorimetry));
    }

    @Override
    public void deleteColorimetrySettings(ColorimetrySettings colorimetrySettings) {
        em.remove(em.merge(colorimetrySettings));
    }

    @Override
    public void deleteComparation(Comparation comparation) {
        em.remove(em.merge(comparation));
    }

    @Override
    public void deleteFormula(Formula formula) {
        em.remove(em.merge(formula));
    }

    @Override
    public void deleteFramework(Framework framework) {
        em.remove(em.merge(framework));
    }

    @Override
    public void deleteGraph(Graph graph) {
        em.remove(em.merge(graph));
    }

    @Override
    public void deleteIcon(Icon icon) {
        em.remove(em.merge(icon));
    }

    @Override
    public void deleteLang(Lang lang) {
        em.remove(em.merge(lang));
    }

    @Override
    public void deleteLicense(License license) {
        em.remove(em.merge(license));
    }

    @Override
    public void deleteMapDrawing(MapDrawing mapDrawing) {
        em.remove(em.merge(mapDrawing));
    }

    @Override
    public void deleteMapDrawingSettings(MapDrawingSettings mapDrawingSettings) {
        em.remove(em.merge(mapDrawingSettings));
    }

    @Override
    public void deleteNoteType(NoteType noteType) {
        em.remove(em.merge(noteType));
    }

    @Override
    public void deleteProfile(Profile profile) {
        em.remove(em.merge(profile));
    }

    @Override
    public void deleteSMTP(SMTP SMTP) {
        em.remove(em.merge(SMTP));
    }

    @Override
    public void deleteTimePeriod(TimePeriod timePeriod) {
        em.remove(em.merge(timePeriod));
    }

    @Override
    public void deleteUnit(Unit unit) {
        em.remove(em.merge(unit));
    }
}//Ends BSCFacade
